package com.mingliqiye.minecraft.enchantment.conflict.forge.network.message;

import static com.mingliqiye.minecraft.enchantment.conflict.forge.network.ChannelHander.CONFIG_CHANNEL_INSTANCE;
import static com.mingliqiye.minecraft.enchantment.conflict.forge.network.ChannelHander.CONFIG_SYNC;

import com.google.gson.Gson;
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigPair;
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
import com.mingliqiye.minecraft.enchantment.conflict.forge.ForgeMod;
import com.mojang.logging.LogUtils;
import java.util.Map;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.event.network.CustomPayloadEvent;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.PacketDistributor;
import org.slf4j.Logger;

public record ConfigMessage(Map<String, ConfigPair> data) {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final Gson GSON = new Gson();

    public static void register() {
        CONFIG_CHANNEL_INSTANCE.messageBuilder(ConfigMessage.class, CONFIG_SYNC, NetworkDirection.PLAY_TO_CLIENT)
            .decoder(ConfigMessage::decode)
            .encoder(ConfigMessage::encode)
            .consumerMainThread(ConfigMessage::handle)
            .add();
    }

    public static void encode(ConfigMessage configMessage, FriendlyByteBuf byteBuf) {
        byteBuf.writeUtf(ConfigManager.toyaml(configMessage.data()));
    }

    public static ConfigMessage decode(FriendlyByteBuf byteBuf) {
        return new ConfigMessage(ConfigManager.fromyaml(byteBuf.readUtf()));
    }

    public static void send(ServerPlayer player) {
        var configItem = ForgeMod.CONFIGMANAGER.getConfig();
        CONFIG_CHANNEL_INSTANCE.send(new ConfigMessage(configItem), PacketDistributor.PLAYER.with(player));
        LOGGER.info(
            "Send Server Config {} to {} data={}",
            MinecraftMod.MOD_ID,
            player.getName().getString(),
            ConfigManager.tojson(configItem)
        );
    }

    public static void handle(ConfigMessage configMessage, CustomPayloadEvent.Context ctx) {
        ctx.enqueueWork(() -> {
            ForgeMod.CONFIGMANAGER.setConfig(configMessage.data());
            LOGGER.info(
                "Load Server Config {} data={}",
                MinecraftMod.MOD_ID,
                ConfigManager.tojson(configMessage.data())
            );
        });
        ctx.setPacketHandled(true);
    }

    public static void sendAll(Map<String, ConfigPair> configPairMap) {
        CONFIG_CHANNEL_INSTANCE.send(new ConfigMessage(configPairMap), PacketDistributor.ALL.noArg());
    }
}
